﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace NFinal.AutoConfig
{
    /// <summary>
    /// 初始化模块时修改*.proj文件类
    /// 修改完成后一定要选择放弃，否则会修改失败
    /// </summary>
    public class Project
    {
        //dl引用实体类
        //public class Assm
        //{
        //    //是否是framework内部引用
        //    public bool IsFrameWork = false;
        //    //引入路径
        //    public Assm(string Include)
        //    {
        //        this.Include = Include;
        //        IsFrameWork = true;
        //    }
        //    //初始化函数
        //    public Assm(string Include, bool SpecificVersion, string HintPath)
        //    {
        //        this.Include = Include;
        //        this.SpecificVersion = SpecificVersion;
        //        this.HintPath = HintPath;
        //        IsFrameWork = false;
        //    }
        //    //获取相关的xml
        //    public XmlNode GetXMLNode(XmlDocument doc, string nameSpace)
        //    {
        //        XmlNode nodeReference = doc.CreateElement("Reference", nameSpace);
        //        XmlAttribute attrInclude = doc.CreateAttribute("Include");
        //        attrInclude.Value = this.Include;
        //        nodeReference.Attributes.Append(attrInclude);
        //        if (!IsFrameWork)
        //        {
        //            XmlNode nodeSpecificVersion = doc.CreateElement("SpecificVersion", nameSpace);
        //            nodeSpecificVersion.InnerText = this.SpecificVersion.ToString();
        //            XmlNode nodeHintPath = doc.CreateElement("HintPath", nameSpace);
        //            nodeHintPath.InnerText = this.HintPath;
        //            nodeReference.AppendChild(nodeSpecificVersion);
        //            nodeReference.AppendChild(nodeHintPath);
        //        }
        //        return nodeReference;
        //    }
        //    public string Include = string.Empty;
        //    public bool SpecificVersion = false;
        //    public string HintPath = string.Empty;
        //}
        private string projectFile=null;
        private XmlNamespaceManager namespaceManager = null;
        private XmlDocument doc = null;
        private string root;
        //private bool hasChanged=false;
        private string nameSpace = null;
        public Project(string projectFile)
        {
            this.projectFile = projectFile;
            this.root= new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName + "\\";
            //修改工程文件,加入dll引入
            doc = new System.Xml.XmlDocument();
            doc.Load(projectFile);
            nameSpace = doc.DocumentElement.Attributes["xmlns"].Value;
            namespaceManager = new XmlNamespaceManager(doc.NameTable);
            namespaceManager.AddNamespace("x", nameSpace);
        }
        public void Save()
        {
            doc.Save(projectFile);
        }
        //将相对根目录的路径转为绝对路径
        public string MapPath(string url)
        {
            return root + url.Trim('/').Replace('/', '\\');
        }
        public string MPath(string url)
        {
            return  url.Replace(root,"")+"\\";
        }
        //public static void CopyLibrary(string root)
        //{
        //    Assm AssmSQLite = new Assm("System.Data.SQLite, Version=1.0.96.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL",
        //false, "NFinal/Resource/System.Data.SQLite.dll");
        //    Assm AssmMySQL = new Assm("MySql.Data, Version=5.1.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL",
        //        false, "NFinal/Resource/MySql.Data.dll");
        //    Assm AssmOracle = new Assm("Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=MSIL",
        //        false, "NFinal/Resource/Oracle.ManagedDataAccess.dll");
        //    System.Collections.Generic.List<Assm> AssmList = new System.Collections.Generic.List<Assm>();
        //    AssmList.Add(AssmSQLite);
        //    AssmList.Add(AssmMySQL);
        //    AssmList.Add(AssmOracle);

        //    //复制文件到执行目录下
        //    string dllFileName = null;
        //    string resourceName = null;
        //    for (int i = 0; i < AssmList.Count; i++)
        //    {
        //        if (!AssmList[i].IsFrameWork)
        //        {
        //            dllFileName = root + "\\bin\\" + Path.GetFileName(AssmList[i].HintPath);
        //            resourceName = root + "\\" + AssmList[i].HintPath.Replace('/', '\\');
        //            if (!File.Exists(dllFileName))
        //            {
        //                File.Copy(resourceName, dllFileName);
        //            }
        //        }
        //    }
        //    //引入32位64位通用dll文件
        //    if (!File.Exists(root + "\\bin\\x64\\SQLite.Interop.dll"))
        //    {
        //        File.Copy(root + "\\NFinal\\Resource\\x64\\SQLite.Interop.dll", GetFileName(root + "\\bin\\x64\\SQLite.Interop.dll"), true);
        //    }
        //    if (!File.Exists(root + "\\bin\\x86\\SQLite.Interop.dll"))
        //    {
        //        File.Copy(root + "\\NFinal\\Resource\\x86\\SQLite.Interop.dll", GetFileName(root + "\\bin\\x86\\SQLite.Interop.dll"), true);
        //    }
        //}
        //添加DLL引用
        //public void AddLibrary()
        //{
        //    Assm AssmSQLite = new Assm("System.Data.SQLite",
        //            false, "NFinal/Resource/System.Data.SQLite.dll");
        //    Assm AssmMySQL = new Assm("MySql.Data",
        //        false, "NFinal/Resource/MySql.Data.dll");
        //    Assm AssmOracle = new Assm("Oracle.ManagedDataAccess",
        //        false,"NFinal/Resource/Oracle.ManagedDataAccess.dll");
        //    Assm AssmNpgsql = new Assm("Npgsql",
        //        false, "NFinal/Resource/Npgsql.dll");
        //    Assm AssmNFinal4 = new Assm("NFinal4",
        //        false,"NFinal/Resource/NFinal4.dll");
        //    System.Collections.Generic.List<Assm> AssmList = new System.Collections.Generic.List<Assm>();
        //    AssmList.Add(AssmSQLite);
        //    AssmList.Add(AssmMySQL);
        //    AssmList.Add(AssmOracle);
        //    AssmList.Add(AssmNpgsql);
        //    AssmList.Add(AssmNFinal4);
        //    AssmList.Add(new Assm("Microsoft.CSharp"));
        //    AssmList.Add(new Assm("System"));
        //    AssmList.Add(new Assm("System.Data"));
        //    AssmList.Add(new Assm("System.Drawing"));
        //    AssmList.Add(new Assm("System.Web"));

        //    //复制文件到执行目录下
        //    string root = Path.GetDirectoryName(projectFile);
        //    string dllFileName = null;
        //    string resourceName = null;
        //    for (int i = 0; i < AssmList.Count; i++)
        //    {
        //        if (!AssmList[i].IsFrameWork)
        //        {
        //            dllFileName = root + "\\bin\\" + Path.GetFileName(AssmList[i].HintPath); 
        //            resourceName = root +"\\"+ AssmList[i].HintPath.Replace('/', '\\');
        //            if (!File.Exists(dllFileName))
        //            {
        //                File.Copy(resourceName, dllFileName);
        //            }
        //        }
        //    }
        //    XmlNode GroupReference = doc.DocumentElement.SelectSingleNode("x:ItemGroup/x:Reference[1]", namespaceManager).ParentNode;
        //    string xpath = null;
        //    for (int i = 0; i < AssmList.Count; i++)
        //    {
        //        xpath = string.Format("x:Reference[@Include='{0}']", AssmList[i].Include);
        //        XmlNode node = GroupReference.SelectSingleNode(xpath, namespaceManager);
        //        if (node == null)
        //        {
        //            GroupReference.AppendChild(AssmList[i].GetXMLNode(doc, nameSpace));
        //        }
        //    }
        //    //去掉Newtonsoft引用
        //    //<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
        //    //< SpecificVersion > False </ SpecificVersion >
        //    //< HintPath > bin\Newtonsoft.Json.dll </ HintPath >
        //    //</ Reference >
        //    XmlNode newtonsoftNode = doc.DocumentElement.SelectSingleNode("x:ItemGroup/x:Reference[contains(@Include,'Newtonsoft.Json')]",namespaceManager);
        //    if (newtonsoftNode != null)
        //    {
        //        newtonsoftNode.ParentNode.RemoveChild(newtonsoftNode);
        //    }
        //    //引入32位64位通用dll文件
        //    if (!File.Exists(root + "\\bin\\x64\\SQLite.Interop.dll"))
        //    {
        //        File.Copy(root + "\\NFinal\\Resource\\x64\\SQLite.Interop.dll",GetFileName(root + "\\bin\\x64\\SQLite.Interop.dll"), true);
        //    }
        //    if (!File.Exists(root + "\\bin\\x86\\SQLite.Interop.dll"))
        //    {
        //        File.Copy(root + "\\NFinal\\Resource\\x86\\SQLite.Interop.dll",GetFileName(root + "\\bin\\x86\\SQLite.Interop.dll"), true);
        //    }
        //}
        public static string GetFileName(string fileName)
        {
            string dir = Path.GetDirectoryName(fileName);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            return fileName;
        }
        public bool hasAdded(string fileName)
        {
            return true;
        }
        /// <summary>
        /// 添加文件夹
        /// </summary>
        /// <param name="folderName"></param>
        public void AddFolder(string folderName)
        {
            //<Folder Include="AA\Models\BLL" />
            string relativeFileName = folderName.Substring(root.Length);
            string folderInclude = string.Format("x:ItemGroup/x:Folder[@Include='{0}']", relativeFileName);
            XmlNode node = doc.DocumentElement.SelectSingleNode(folderInclude,namespaceManager);
            if (node == null)
            {
                XmlNode GroupInclude= doc.DocumentElement.SelectSingleNode("x:ItemGroup[2]", namespaceManager);
                XmlNode FolderNode = doc.CreateElement("Folder", nameSpace);
                XmlAttribute FolderNodeIncludeAttr = doc.CreateAttribute("Include");
                FolderNodeIncludeAttr.Value = relativeFileName;
                FolderNode.Attributes.Append(FolderNodeIncludeAttr);
                GroupInclude.AppendChild(FolderNode);
            }
        }
        /// <summary>
        /// 添加文件
        /// </summary>
        /// <param name="fileName"></param>
        public  void AddFile(string fileName)
        {
            XmlNode GroupInclude = doc.DocumentElement.SelectSingleNode("x:ItemGroup[2]", namespaceManager);
            string relativeFileName = fileName.Substring(root.Length);
            string shortFileName = Path.GetFileName(fileName);
            if (fileName.EndsWith(".cs"))
            {
                //截取Include值
                string compileInclude = string.Format("x:ItemGroup/x:Compile[@Include='{0}']", relativeFileName);
                XmlNode node = doc.DocumentElement.SelectSingleNode(compileInclude, namespaceManager);
                if (node == null)
                {
                    //<Compile Include="App\Handler1.ashx.cs">
                    //</Compile>
                    XmlNode CompileNode = doc.CreateElement("Compile", nameSpace);
                    XmlAttribute CompileNodeIncludeAttr = doc.CreateAttribute("Include");
                    CompileNodeIncludeAttr.Value = relativeFileName;
                    CompileNode.Attributes.Append(CompileNodeIncludeAttr);
                    //<Compile Include="App\Handler1.ashx.cs">
                    //< DependentUpon > Handler1.ashx </ DependentUpon >
                    //</ Compile >
                    if (fileName.EndsWith(".ashx.cs"))
                    {
                        XmlNode DependentUponNode = doc.CreateElement("DependentUpon", nameSpace);
                        DependentUponNode.InnerText =shortFileName.Substring(0, shortFileName.Length - 3);
                        CompileNode.AppendChild(DependentUponNode);
                    }
                    //<Compile Include="App\Views\Default\Common\Public\Success.aspx.cs">
                    //< DependentUpon > Success.aspx </ DependentUpon >
                    //< SubType > ASPXCodeBehind </ SubType >
                    //</ Compile >
                    else if (fileName.EndsWith(".aspx.cs"))
                    {
                        XmlNode DependentUponNode = doc.CreateElement("DependentUpon", nameSpace);
                        DependentUponNode.InnerText = shortFileName.Substring(0, shortFileName.Length - 3);
                        XmlNode SubTypeNode = doc.CreateElement("SubType", nameSpace);
                        SubTypeNode.InnerText = "ASPXCodeBehind";
                        CompileNode.AppendChild(DependentUponNode);
                        CompileNode.AppendChild(SubTypeNode);
                    }
                    //<Compile Include="App\Views\Default\Common\Public\Success.aspx.designer.cs">
                    //< DependentUpon > Success.aspx </ DependentUpon >
                    //</ Compile >
                    else if (fileName.EndsWith(".designer.cs"))
                    {
                        XmlNode DependentUponNode = doc.CreateElement("DependentUpon", nameSpace);
                        DependentUponNode.InnerText = shortFileName.Substring(0, shortFileName.Length - 12);
                        CompileNode.AppendChild(DependentUponNode);
                    }
                    //<Compile Include="App\Views\Default\Common\Public\Footer.ascx.designer.cs">
                    //< DependentUpon > Footer.ascx </ DependentUpon >
                    //</ Compile >
                    else if (fileName.EndsWith(".ascx.cs"))
                    {
                        XmlNode DependentUponNode = doc.CreateElement("DependentUpon", nameSpace);
                        DependentUponNode.InnerText = shortFileName.Substring(0, shortFileName.Length - 3);
                        XmlNode SubTypeNode = doc.CreateElement("SubType", nameSpace);
                        SubTypeNode.InnerText = "ASPXCodeBehind";
                        CompileNode.AppendChild(DependentUponNode);
                        CompileNode.AppendChild(SubTypeNode);
                    }
                    //<Compile Include="App\Models\Tips\Common\users.cs" />
                    else
                    {
                        XmlNode SubTypeNode = doc.CreateElement("SubType", nameSpace);
                        SubTypeNode.InnerText = "Code";
                        CompileNode.AppendChild(SubTypeNode);
                    }
                    GroupInclude.AppendChild(CompileNode);
                }
            }
            else if (fileName.EndsWith(".Debug.config") || fileName.EndsWith(".Release.config"))
            {
            }
            else
            {
                string fileInclude = string.Format("x:ItemGroup/x:Content[@Include='{0}']", relativeFileName);
                XmlNode node = doc.DocumentElement.SelectSingleNode(fileInclude, namespaceManager);
                if (node == null)
                {
                    XmlNode ContentNode = doc.CreateElement("Content", nameSpace);
                    XmlAttribute ContentNodeIncludeAttr = doc.CreateAttribute("Include");
                    ContentNodeIncludeAttr.Value = relativeFileName;
                    ContentNode.Attributes.Append(ContentNodeIncludeAttr);
                    GroupInclude.AppendChild(ContentNode);
                }
            }
        }
        /// <summary>
        /// 添加文件夹下所有文件
        /// </summary>
        /// <param name="folder"></param>
        public void AddFiles(string folder)
        {
            AddFolder(folder);
            string[] fileNames = Directory.GetFiles(folder);//查找指定目录下文件名
            foreach (string fileName in fileNames)
            {
                AddFile(fileName);
            }
            string[] folderNames = Directory.GetDirectories(folder);//查询指定路径下的子目录
            foreach (string folderName in folderNames)
            {
                AddFiles(folderName);
            }
        }
        /// <summary>
        /// 添加模块
        /// </summary>
        /// <param name="folder"></param>
        public void AddModule(string folder)
        {
            AddFiles(folder);
            
        }
    }
}
